package com.customization.unionpay.market.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.customization.unionpay.market.service.DailyReportButtonService;
import com.customization.unionpay.market.maketEnum.InstructionEnum;
import com.customization.unionpay.market.util.AccountingEngineUtils;
import com.engine.core.impl.Service;
import org.apache.commons.lang.StringUtils;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.hrm.company.DepartmentComInfo;
import weaver.hrm.company.SubCompanyComInfo;
import weaver.hrm.resource.ResourceComInfo;
import weaver.integration.logging.Logger;
import weaver.integration.logging.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

public class DailyReportButtonServiceImpl extends Service implements DailyReportButtonService {

    private static final Logger log = LoggerFactory.getLogger(DailyReportButtonServiceImpl.class);

    @Override
    public String dailyReportPaymentRequest(String ids, User user) throws Exception {
        // 2种资金来源、4种活动类型和2种收款账户
        // TODO 同步资金账户类型
        String result = null;

        // 营销活动日报表台账表单id
        int marketingActivityDailyReportFormId = Integer.parseInt(com.customization.unionpay.market.util.PropUtils.BB_LOG.getPropValue("marketSubject", "marketing_activity_daily_report_form_id"));

        // 日报表内置映射参数表单id
        int dailyReportBuiltParamsFormId = Integer.parseInt(com.customization.unionpay.market.util.PropUtils.BB_LOG.getPropValue("marketSubject", "daily_report_built_params_form_id"));

        // 日报表内置映射表单id
        int dailyReportBuiltMappingFormId = Integer.parseInt(com.customization.unionpay.market.util.PropUtils.BB_LOG.getPropValue("marketSubject", "daily_report_built_mapping_form_id"));
        // 日报表内置映射模块id
        int dailyReportBuiltMappingFormmodeId = Integer.parseInt(com.customization.unionpay.market.util.PropUtils.BB_LOG.getPropValue("marketSubject", "daily_report_built_mapping_formmode_id"));

        String dailyReportTableName = com.customization.unionpay.market.util.FormDataUtils.getTableName(marketingActivityDailyReportFormId);
        log.info("dailyReportTableName：" + dailyReportTableName);
        // 中间表
        String dailyReportBuiltMappingTableName = com.customization.unionpay.market.util.FormDataUtils.getTableName(dailyReportBuiltMappingFormId);
        log.info("dailyReportBuiltMappingTableName：" + dailyReportBuiltMappingTableName);
        // 配置表
        String dailyReportBuiltParamsTableName = com.customization.unionpay.market.util.FormDataUtils.getTableName(dailyReportBuiltParamsFormId);
        log.info("dailyReportBuiltParamsTableName：" + dailyReportBuiltParamsTableName);

        String yrzValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(marketingActivityDailyReportFormId, "zt", "已入账");
        log.info("已入账枚举值：" + yrzValue);
        String fzsbValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(marketingActivityDailyReportFormId, "zt", "付款失败");
        log.info("付款失败枚举值：" + fzsbValue);
        String qkspzValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(marketingActivityDailyReportFormId, "zt", "请款审批中");
        log.info("请款审批中枚举值：" + qkspzValue);

        String zxsjValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(marketingActivityDailyReportFormId, "rblslx", "正常数据");
        log.info("正常数据枚举值：" + zxsjValue);
        String hdjebgsjValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(marketingActivityDailyReportFormId, "rblslx", "核定金额变更数据");
        log.info("核定金额变更数据枚举值：" + hdjebgsjValue);

        String zjlyIsSValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(dailyReportBuiltParamsFormId, "zjly", "启用");
        log.info("资金来源启动：" + zjlyIsSValue);
        String actTpIsSValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(dailyReportBuiltParamsFormId, "ACT_TP", "启用");
        log.info("活动类型启用：" + actTpIsSValue);
        String sqmwhIsSValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(dailyReportBuiltParamsFormId, "sqmwh", "启用");
        log.info("授权码尾号启用：" + sqmwhIsSValue);
        // zjly ACT_TP sqmwh
        JSONObject jsons = com.customization.unionpay.market.util.DailyReportRelated.selectDailyParams(dailyReportBuiltParamsTableName);

        boolean sqmwhIsSearch = false;
        String sqmwhIsS = jsons.getString("sqmwh");
        log.info("sqmwhIsS：" + sqmwhIsS);
        if (sqmwhIsSValue.equals(sqmwhIsS)) {
            sqmwhIsSearch = true;
        }
        // 【状态】为“已入账”或“付款失败” 【日报流水类型】为“正常数据“或“核定金额变更数据”
        List<JSONObject> list = com.customization.unionpay.market.util.DailyReportRelated.selectDailyReportInfoByIds(dailyReportTableName, ids);
        if (list.size() > 0) {
            JSONObject resultJson = new JSONObject();
            for (JSONObject json : list) {
                String id = json.getString("id");
                String zt = json.getString("zt");
                String rblslx = json.getString("rblslx");
                if (zt.equals(yrzValue) || zt.equals(fzsbValue)) {
                    if (rblslx.equals(zxsjValue) || rblslx.equals(hdjebgsjValue)) {
                        String zjly = Util.null2String(json.getString("zjly"));
                        String actTp = Util.null2String(json.getString("ACT_TP"));
                        String sqmwh = Util.null2String(json.getString("sqmwh"));
                        log.info("sqmwh:" + sqmwh);
                        Double rzje = json.getDouble("rzje") == null ? 0 : json.getDouble("rzje");
                        log.info("rzje:" + rzje);
                        // 随机批次号
                        String uuid = UUID.randomUUID().toString();
                        if (sqmwhIsSearch) {
                            String number = sqmwh.substring(sqmwh.length() - 1);
                            String onlyValue = zjly + actTp + number;
                            resultJson = parseDataByOnlyValue(resultJson, onlyValue, id, rzje, uuid, qkspzValue, actTp, zjly, number, dailyReportTableName, marketingActivityDailyReportFormId, dailyReportBuiltMappingFormId);
                        } else {
                            String onlyValue = zjly + actTp;
                            resultJson = parseDataByOnlyValue(resultJson, onlyValue, id, rzje, uuid, qkspzValue, actTp, zjly, "", dailyReportTableName, marketingActivityDailyReportFormId, dailyReportBuiltMappingFormId);
                        }
                    } else {
                        if (result != null) {
                            result += "," + "营销活动日报表清算请款数据id:" + id + "的日报流水类型不是正常数据或者核定金额变更数据！";
                        } else {
                            result = "";
                            result += "营销活动日报表清算请款数据id:" + id + "的日报流水类型不是正常数据或者核定金额变更数据！";
                        }
                    }
                } else {
                    if (result != null) {
                        result += "," + "营销活动日报表清算请款数据id:" + id + "的状态不是已入账或者付款失败！";
                    } else {
                        result = "";
                        result += "营销活动日报表清算请款数据id:" + id + "的状态不是已入账或者付款失败！";
                    }
                }
            }
            if (resultJson.size() > 0) {
                Double ad = 0D;
                for (Object key : resultJson.keySet()) {
                    JSONObject res = resultJson.getJSONObject((String) key);
                    // 请款批次号
                    String qkpch = res.getString("qkpch");
                    // 资金来源
                    String zjly = res.getString("zjly");
                    // 活动类型
                    String hdlx = res.getString("hdlx");
                    // 分类
                    String fl = res.getString("fl");
                    // 付款摘要
                    String fkzy = res.getString("fkzy");
                    // 汇总金额
                    String hzje = res.getString("hzje");
                    ad += res.getDouble("hzje");
                    // 划拨类型
                    String hblx = res.getString("hblx");
                    // 结算方式
                    String jsfs = res.getString("jsfs");
                    // 授权码尾号
                    String sqmwh = res.getString("sqmwh");
                    // 付款账户
                    String fkzh = res.getString("fkzh");
                    // 付款账户开户行
                    String fkzhkhh = res.getString("fkzhkhh");
                    // 付款账户支行
                    String fkzhzh = res.getString("fkzhzh");
                    // 付款账户银行账号
                    String fkzhyhzh = res.getString("fkzhyhzh");
                    // 收款账户
                    String skzh = res.getString("skzh");
                    // 收款账户开户行
                    String skzhkhh = res.getString("skzhkhh");
                    // 收款账户支行
                    String skzhzh = res.getString("skzhzh");
                    // 收款账户银行账号
                    String skzhyhzh = res.getString("skzhyhzh");

                    com.customization.unionpay.market.util.DailyReportBuiltMapping.addDailyReportData(dailyReportBuiltMappingFormId, dailyReportBuiltMappingFormmodeId, user, dailyReportBuiltMappingTableName,
                            qkpch, zjly, hdlx, fl, fkzy, hzje, hblx, jsfs, fkzh, fkzhkhh, fkzhzh, fkzhyhzh, skzh, skzhkhh, skzhzh, skzhyhzh, sqmwh);
                }


                log.info("总体金额：" + String.valueOf(ad));
                String requestId = changeWorkFlowData(resultJson, user, String.valueOf(ad));
                log.info("资金划拨单requestId：" + requestId);
            }
        } else {
            result = "";
            result += "查询选中数据异常！";
        }
        return result;
    }

    @Override
    public String dailyReportAccountingEntry(String ids, String rzDate, User user) throws Exception {

        // 勾选台账‘正常数据’“活动结束后交易数据”，且状态=“已确认未入账”或“入账失败”
        String result = null;

        // 营销活动日报表台账表单id
        int marketingActivityDailyReportFormId = Integer.parseInt(com.customization.unionpay.market.util.PropUtils.BB_LOG.getPropValue("marketSubject", "marketing_activity_daily_report_form_id"));

        // # 营销事项申请流程id
        String marketingApplicationWorkId = com.customization.unionpay.market.util.PropUtils.BB_LOG.getPropValue("marketSubject", "marketing_application_work_id");

        String dailyReportTableName = com.customization.unionpay.market.util.FormDataUtils.getTableName(marketingActivityDailyReportFormId);
        log.info("dailyReportTableName：" + dailyReportTableName);

        // 已确认未入账 入账中、已入账、入账失败
        String yqrwrzValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(marketingActivityDailyReportFormId, "zt", "已确认未入账");
        log.info("已确认未入账枚举值：" + yqrwrzValue);
        String rzzValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(marketingActivityDailyReportFormId, "zt", "入账中");
        log.info("入账中枚举值：" + rzzValue);
        String yrzValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(marketingActivityDailyReportFormId, "zt", "已入账");
        log.info("已入账枚举值：" + yrzValue);
        String rzsbValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(marketingActivityDailyReportFormId, "zt", "入账失败");
        log.info("入账失败枚举值：" + rzsbValue);


        String zxsjValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(marketingActivityDailyReportFormId, "rblslx", "正常数据");
        log.info("正常数据枚举值：" + zxsjValue);
        String hdjebgsjValue = com.customization.unionpay.market.util.FormDataUtils.getItemValue(marketingActivityDailyReportFormId, "rblslx", "核定金额变更数据");
        log.info("核定金额变更数据枚举值：" + hdjebgsjValue);

        String workFlowTableName = com.customization.unionpay.market.util.FormDataUtils.getWorkFlowTableName(marketingApplicationWorkId);
        log.info("申请单主表表名：" + workFlowTableName);

        // 会计引擎中间表表单id
        int kjyqFormId = Integer.parseInt(com.customization.unionpay.market.util.PropUtils.BB_LOG.getPropValue("marketSubject", "kjyq_form_id"));
        // 会计引擎中间表模块id
        int kjyqFormmodeId = Integer.parseInt(com.customization.unionpay.market.util.PropUtils.BB_LOG.getPropValue("marketSubject", "kjyq_formmode_id"));

        // 会计引擎中间表台账
        String kjyqTableName = com.customization.unionpay.market.util.FormDataUtils.getTableName(kjyqFormId);
        log.info("会计引擎中间表台账：" + kjyqTableName);

        try {
            ResourceComInfo rci = new ResourceComInfo();
            DepartmentComInfo dci = new DepartmentComInfo();
            SubCompanyComInfo scci = new SubCompanyComInfo();

            String workcode = rci.getWorkcode(String.valueOf(user.getUID()));

            // 【状态】为“已确认未入账”或“入账失败” 【日报流水类型】为“正常数据“或“核定金额变更数据”
            List<JSONObject> list = com.customization.unionpay.market.util.DailyReportRelated.selectDailyReportInfoByIds(dailyReportTableName, ids);
            if (list.size() > 0) {
                Date date = new Date();
                String nowDate = new SimpleDateFormat("yyyy-MM-dd").format(date);
                int userUID = user.getUID();
                String useId = String.valueOf(userUID);
                String personId = com.customization.unionpay.market.util.FormDataUtils.getPersonByRoleName("财务主管");
                List<JSONObject> detailsList = new ArrayList<>();
                JSONObject mainParams = new JSONObject();
                mainParams.put("lydjlx", "日报表核算入账");
                // 入账批次号
                String rzpch = UUID.randomUUID().toString();
                log.info("rzpch：" + rzpch);
                for (JSONObject json : list) {
                    String id = json.getString("id");
                    String zt = json.getString("zt");
                    String rblslx = json.getString("rblslx");
                    if (zt.equals(yqrwrzValue) || zt.equals(rzsbValue)) {
                        if (rblslx.equals(zxsjValue) || rblslx.equals(hdjebgsjValue)) {
                            String zjly = json.getString("zjly");
                            String actTp = json.getString("ACT_TP");

                            String jbr = json.getString("jbr");
                            String qsrq = json.getString("qsrq");
                            String qsje = json.getString("qsje");

                            String yxpthdsqm = json.getString("yxpthdsqm");
                            String yxptsxsqdh = json.getString("yxptsxsqdh");

                            // 预算 入账金额     资金来源＝内部营销                       点击按钮-释放占用且执行
                            //                 资金来源＝内外部联合营销                  点击按钮-释放占用且执行
                            if (yxptsxsqdh != null && !"".equals(yxptsxsqdh)) {
                                // 查询营销事项申请单
                                JSONObject marketingApplicationInfo = com.customization.unionpay.market.util.FormDataUtils.getMarketingApplicationInfo(yxptsxsqdh, workFlowTableName);
                                log.info("查询营销事项申请单数据：" + marketingApplicationInfo);
                                if (marketingApplicationInfo != null) {
                                    List<JSONObject> dailyReportToMarketingApplicationParams = getDailyReportToMarketingApplicationParams(yxptsxsqdh, qsje, marketingApplicationInfo, InstructionEnum.SFZYQZX.toString(), user);
                                    log.info("预算校验拼接参数：" + dailyReportToMarketingApplicationParams);

                                    String budgetVerify = com.customization.unionpay.market.util.BudgetManagementUtils.budgetExecBudget(id, workcode, dailyReportToMarketingApplicationParams);
                                    JSONObject resultJson = JSONObject.parseObject(budgetVerify);
                                    log.info("预算校验返回参数：" + resultJson);

                                    boolean b = resultJson.containsKey("status");
                                    log.info("预算执行返回参数一级是否包含status：" + b);
                                    if (b) {
                                        String status = resultJson.getString("status");
                                        if (!"1".equals(status)) {
                                            String errorMessage = resultJson.getString("errorMessage");
                                            if (result != null) {
                                                result += "," + "营销活动日报表核算入账数据id:" + errorMessage;
                                            } else {
                                                result = "";
                                                result += "营销活动日报表核算入账数据id:" + errorMessage;
                                            }
                                            // 预算调用失败，入账失败
                                            com.customization.unionpay.market.util.DailyReportRelated.updateZtById(id, rzsbValue, dailyReportTableName);
                                        }
                                    } else {
                                        StringBuilder err = null;
                                        JSONArray resultDetail = resultJson.getJSONArray("result");
                                        for (int i = 0; i < resultDetail.size(); i++) {
                                            JSONObject jsonObject = resultDetail.getJSONObject(i);
                                            String statusDetail = jsonObject.getString("status");
                                            if ("-1".equals(statusDetail) || "-11".equals(statusDetail) || "-".contains(statusDetail)) {
                                                String errorMessage = jsonObject.getString("errorMessage");
                                                if (err == null) {
                                                    err = new StringBuilder();
                                                    err.append(errorMessage).append("，");
                                                } else {
                                                    err.append(errorMessage).append("，");
                                                }
                                            } else {
                                                JSONObject data = jsonObject.getJSONObject("data");
                                                log.info("data:" + data);
                                            }
                                        }

                                        if (err != null) {
                                            err.deleteCharAt(err.length() - 1).append("!");
                                            log.error("err：" + err);
                                            com.customization.unionpay.market.util.DailyReportRelated.updateZtById(id, rzsbValue, dailyReportTableName);
                                            if (result != null) {
                                                result += "," + "营销活动日报表核算入账数据id:" + err.toString();
                                            } else {
                                                result = "";
                                                result += "营销活动日报表核算入账数据id:" + err.toString();
                                            }
                                        } else {
                                            log.info("预算相关调用成功");

                                            // 入账日期，入账金额(清算金额)修改
                                            com.customization.unionpay.market.util.DailyReportRelated.updateRzrqAndRzjeById(rzDate, qsje, id, dailyReportTableName);
                                            // 预算调用成功，写入入账批次号
                                            com.customization.unionpay.market.util.DailyReportRelated.updateRZPchById(rzpch, id, dailyReportTableName);

                                            // 修改状态入账中 TODO 临时情况
                                            com.customization.unionpay.market.util.DailyReportRelated.updateZtByRZPch(rzpch, yrzValue, dailyReportTableName);

                                            // 会计引擎相关
                                            String workCode = rci.getWorkcode(jbr);
                                            log.info("workCode：" + workCode);
                                            // 报账部门			                        经办人部门（不传浪潮，返回到表单凭证明细）	经办人部门	        jbrbm
                                            String departmentId = rci.getDepartmentID(jbr);
                                            String departmentCode = dci.getDepartmentCode(departmentId);
                                            log.info("departmentCode：" + departmentCode);
                                            // 主办单位			                        经办人公司（不传浪潮，返回到表单凭证明细）	经办人公司	        jbrgs
                                            String subCompanyId = rci.getSubCompanyID(jbr);
                                            String subCompanyCode = scci.getSubCompanyname(subCompanyId);
                                            log.info("subCompanyCode：" + subCompanyCode);
                                            // 活动类型		    取名称	                摘要	                                活动类型名称	        hdlx
                                            String actTpName = com.customization.unionpay.market.util.FormDataUtils.getItemName(marketingActivityDailyReportFormId, "ACT_TP", actTp);
                                            log.info("actTpName：" + actTpName);
                                            String actTpCode = com.customization.unionpay.market.util.FormDataUtils.hdlxName(actTpName);
                                            //  zjly        资金来源			                        出资方式	                            资金来源	            zjly
                                            String zjlyName = com.customization.unionpay.market.util.FormDataUtils.getItemName(marketingActivityDailyReportFormId, "zjly", zjly);
                                            log.info("zjlyName：" + zjlyName);
                                            String zjlyCode = com.customization.unionpay.market.util.FormDataUtils.czfsName(zjlyName);
                                            // 经济事项编码		取编码	                映射表字段	                        经济事项编码	        jjsxbm
                                            String jjsx = marketingApplicationInfo.getString("jjsx");

                                            JSONObject params = new JSONObject();
                                            // 核算主体			    (单号查)   zth          法人公司	        核算主体编码	hsztbm	核算主体
                                            String zth = marketingApplicationInfo.getString("zth");
                                            Object hszt = mainParams.get("hszt");
                                            if (hszt == null || "".equals(hszt)) {
                                                mainParams.put("hszt", zth);
                                            }
                                            // nowDate 结算日期	     		jsrq		           凭证日期、头文本	入账日期	    rzrq	入账日期
                                            Object rzrq = mainParams.get("rzrq");
                                            if (rzrq == null || "".equals(rzrq)) {
                                                mainParams.put("rzrq", rzDate);
                                            }
                                            // rzpch 入账批次号	rzpch		           备选参考编号	    表单号	    bdh	    表单号
                                            Object bdh = mainParams.get("bdh");
                                            if (bdh == null || "".equals(bdh)) {
                                                mainParams.put("bdh", rzpch);
                                            }
                                            // useId          凭证制单人				触发【核算入账】的用户ID	凭证制单人	    凭证制单人	zhidanren	凭证制单人
                                            Object pzzdr = mainParams.get("pzzdr");
                                            if (pzzdr == null || "".equals(pzzdr)) {
                                                mainParams.put("pzzdr", useId);
                                            }
                                            // personId       凭证复核人				财务主管	                凭证复核人	    凭证复核人	fuheren	    凭证复核人
                                            Object pzfhr = mainParams.get("pzfhr");
                                            if (pzfhr == null || "".equals(pzfhr)) {
                                                mainParams.put("pzfhr", personId);
                                            }
                                            // workCode       经办人					       经办人（不传浪潮，返回到表单凭证明细）	    经办人	    jbr	    经办人
                                            Object jbrC = mainParams.get("jbr");
                                            if (jbrC == null || "".equals(jbrC)) {
                                                mainParams.put("jbr", useId);
                                            }
                                            // departmentCode 部门	        		 		   经办人部门（不传浪潮，返回到表单凭证明细）	经办人部门	jbrbm	经办人部门
                                            Object jbrbm = mainParams.get("jbrbm");
                                            if (jbrbm == null || "".equals(jbrbm)) {
                                                mainParams.put("jbrbm", departmentId);
                                            }
                                            // subCompanyCode 公司	        		 		   经办人公司（不传浪潮，返回到表单凭证明细）	经办人公司	jbrgs	经办人公司
                                            Object jbrgs = mainParams.get("jbrgs");
                                            if (jbrgs == null || "".equals(jbrgs)) {
                                                mainParams.put("jbrgs", subCompanyId);
                                            }

                                            // 营销事项申请单号   yxptsxsqdh             字段7       zd7
                                            params.put("zd7", yxptsxsqdh);
                                            // 经济事项   jisx                         经济事项1    jjsx1
                                            params.put("jjsx1", jjsx);
                                            // 活动类型   hdlx                         行摘要       hzy     取名称
                                            params.put("hzy", actTpName);
                                            // 活动类型   hdlx                         活动类型1    hdlx1    取编码
                                            params.put("hdlx1", actTpCode);
                                            // 资金来源   zjly                         出资方式1    czfs1
                                            params.put("czfs1", zjlyCode);
                                            // 日报流水类型    rblslx 转换金额
                                            String rbl = "1000013";
                                            if(rblslx.equals(hdjebgsjValue)){
                                                rbl = "1000016";
                                            }
                                            params.put("rblslx", rbl);
                                            // 清算日期               qsrq                字段6     zd6
                                            params.put("zd6", qsrq);
                                            // 营销平台活动授权码      yxpthdsqm            字段8     zd8
                                            params.put("zd8", yxpthdsqm);
                                            // 清算金额               qsje                金额2      je2
                                            params.put("je2", qsje);
                                            // 清算金额*内部使用比例    qsje                金额1       je1
                                            params.put("je1", qsje);
                                            detailsList.add(params);
                                        }
                                    }
                                } else {
                                    // 的原事项申请单号的数据为空，入账失败
                                    com.customization.unionpay.market.util.DailyReportRelated.updateZtById(id, rzsbValue, dailyReportTableName);
                                    if (result != null) {
                                        result += "," + "营销活动日报表核算入账数据id:" + id + "的原事项申请单号的数据为空！";
                                    } else {
                                        result = "";
                                        result += "营销活动日报表核算入账数据id:" + id + "的原事项申请单号的数据为空！";
                                    }
                                }
                            } else {
                                // 原事项申请单号为空，入账失败
                                com.customization.unionpay.market.util.DailyReportRelated.updateZtById(id, rzsbValue, dailyReportTableName);
                                if (result != null) {
                                    result += "," + "营销活动日报表核算入账数据id:" + id + "的原事项申请单号为空！";
                                } else {
                                    result = "";
                                    result += "营销活动日报表核算入账数据id:" + id + "的原事项申请单号为空！";
                                }
                            }
                        } else {
                            if (result != null) {
                                result += "," + "营销活动日报表核算入账数据id:" + id + "的日报流水类型不是正常数据或者核定金额变更数据！";
                            } else {
                                result = "";
                                result += "营销活动日报表核算入账数据id:" + id + "的日报流水类型不是正常数据或者核定金额变更数据！";
                            }
                        }
                    } else {
                        if (result != null) {
                            result += "," + "营销活动日报表核算入账数据id:" + id + "的状态不是已确认未入账或者入账失败！";
                        } else {
                            result = "";
                            result += "营销活动日报表核算入账数据id:" + id + "的状态不是已确认未入账或者入账失败！";
                        }
                    }
                }

                // TODO 凭证号 pzh
                log.info("mainParams:" + mainParams + ",detailsList:" + detailsList);
                if (mainParams.size() > 0 && detailsList.size() > 0) {
                    int dt3 = com.customization.unionpay.market.util.FormDataUtils.addMainAndDetailsData(kjyqFormId, kjyqFormmodeId, user, kjyqTableName, "_dt3", mainParams, detailsList);
                    if (dt3 != -1) {
                        log.info("冲销会计引擎中间表推送成功！");
                        try {
                            JSONObject resultAccountingEngine = AccountingEngineUtils.pushAccountingEngine(String.valueOf(dt3), "营销日报表台账", user);

                            // 推入中间表成功，修改状态入账中
                            com.customization.unionpay.market.util.DailyReportRelated.updateZtByRZPch(rzpch, yrzValue, dailyReportTableName);
                        } catch (Exception e) {
                            log.error("中间表推送会计引擎异常：" + e.getMessage());
                            log.error("删除中间表对应主表和明细表的数据：" + dt3);
                            com.customization.unionpay.market.util.ClearFundButtonRelated.deleteByBillId(kjyqTableName, dt3);
                            com.customization.unionpay.market.util.ClearFundButtonRelated.deleteDetailsByBillId(kjyqTableName + "_dt3", dt3);

                            if (result != null) {
                                result += "," + "推送入账批次号为：" + rzpch + "的营销日报表数据到中间表推送会计引擎异常：" + e.getMessage();
                            } else {
                                result = "";
                                result += "推送入账批次号为：" + rzpch + "的营销日报表数据到中间表推送会计引擎异常：" + e.getMessage();
                            }
                        }
                    } else {
                        // 推入中间表失败，修改状态入账失败
                        com.customization.unionpay.market.util.DailyReportRelated.updateZtByRZPch(rzpch, rzsbValue, dailyReportTableName);
                        if (result != null) {
                            result += "," + "推送入账批次号为：" + rzpch + "的营销日报表数据到会计引擎中间表失败！";
                        } else {
                            result = "";
                            result += "推送入账批次号为：" + rzpch + "的营销日报表数据到会计引擎中间表失败！";
                        }
                    }
                } else {
                    // 推入中间表异常，修改状态入账失败
                    com.customization.unionpay.market.util.DailyReportRelated.updateZtByRZPch(rzpch, rzsbValue, dailyReportTableName);

                    if (result != null) {
                        result += "," + "获取入账批次号为：" + rzpch + "营销日报表数据为空！";
                    } else {
                        result = "";
                        result += "获取入账批次号为：" + rzpch + "营销日报表数据为空！";
                    }
                }
            } else {
                if (result != null) {
                    result += ",查询选中数据异常";
                } else {
                    result = "";
                    result += "查询选中数据异常";
                }
            }
        } catch (Exception e) {
            if (result != null) {
                result += "," + e.getMessage();
            } else {
                result = "";
                result += e.getMessage();
            }
        }
        return result;
    }

    /**
     * 分类枚举转换
     *
     * @param itemName
     * @return
     */
    private String changeItemValue(String itemName) {
        String result = null;
        if ("立减".equals(itemName)) {
            result = "立减";
        } else if ("积分（普通）".equals(itemName) || "积分（消费送红包）".equals(itemName)) {
            result = "积分";
        } else if ("奖励金".equals(itemName)) {
            result = "奖励金";
        }
        return result;
    }

    /**
     * 组合中间表数据
     *
     * @param resultJson
     * @param onlyValue
     * @param id
     * @param rzje
     * @param uuid
     * @param qkspzValue
     * @param actTp
     * @param zjly
     * @param sqmwh
     * @param dailyReportTableName
     * @param marketingActivityDailyReportFormId
     * @param dailyReportBuiltMappingFormId
     * @return
     */
    private JSONObject parseDataByOnlyValue(JSONObject resultJson, String onlyValue, String id, Double rzje, String uuid, String qkspzValue, String actTp, String zjly, String sqmwh, String dailyReportTableName, int marketingActivityDailyReportFormId, int dailyReportBuiltMappingFormId) {

        // 唯一值
        Object rjson = resultJson.get(onlyValue);
        if (rjson != null) {

            JSONObject singleData = resultJson.getJSONObject(onlyValue);
            Double hzje = singleData.getDouble("hzje") + rzje;
            // 汇总金额
            singleData.put("hzje", hzje);
            resultJson.put(onlyValue, singleData);

            // 请款批次号
            String qkpch = singleData.getString("qkpch");
            // 修改日报表状态和请款批次号
            com.customization.unionpay.market.util.DailyReportRelated.updatePchAndZtById(id, qkpch, qkspzValue, dailyReportTableName);

        } else {
            // 修改日报表状态和请款批次号
            com.customization.unionpay.market.util.DailyReportRelated.updatePchAndZtById(id, uuid, qkspzValue, dailyReportTableName);

            JSONObject singleData = new JSONObject();
            // 请款批次号
            singleData.put("qkpch", uuid);
            // 资金来源
            singleData.put("zjly", zjly);
            // 活动类型
            singleData.put("hdlx", actTp);
            String actItemName = com.customization.unionpay.market.util.FormDataUtils.getItemName(marketingActivityDailyReportFormId, "ACT_TP", actTp);
            String actTpz = changeItemValue(actItemName);
            // 分类
            String fl = com.customization.unionpay.market.util.FormDataUtils.getItemValue(dailyReportBuiltMappingFormId, "fl", actTpz);
            log.info("分类：" + fl);
            singleData.put("fl", fl);
            // 付款摘要
            String zjItemName = com.customization.unionpay.market.util.FormDataUtils.getItemName(marketingActivityDailyReportFormId, "zjly", zjly);
            String fkzy = zjItemName + actTpz;
            singleData.put("fkzy", fkzy);
            // 汇总金额
            singleData.put("hzje", rzje);
            // 划拨类型
            String hblx = com.customization.unionpay.market.util.FormDataUtils.getItemValue(dailyReportBuiltMappingFormId, "hblx", "营销资金补足");
            singleData.put("hblx", hblx);
            // 结算方式
            String jsfs = com.customization.unionpay.market.util.FormDataUtils.getItemValue(dailyReportBuiltMappingFormId, "jsfs", "银行转账");
            log.info("结算方式：" + jsfs);
            singleData.put("jsfs", jsfs);
            // 授权码尾号
            if (sqmwh != null && !"".equals(sqmwh)) {
                singleData.put("sqmwh", sqmwh);
            }
            JSONObject mappingData = getMappingData(actTp, zjly, sqmwh);
            if (mappingData != null) {
                singleData.put("fkzh", mappingData.getString("fkzh"));
                singleData.put("fkzhkhh", mappingData.getString("fkzhkhh"));
                singleData.put("fkzhzh", mappingData.getString("fkzhzh"));
                singleData.put("fkzhyhzh", mappingData.getString("fkzhyhzh"));
                singleData.put("skzh", mappingData.getString("skzh"));
                singleData.put("skzhkhh", mappingData.getString("skzhkhh"));
                singleData.put("skzhzh", mappingData.getString("skzhzh"));
                singleData.put("skzhyhzh", mappingData.getString("skzhyhzh"));
                singleData.put("fkdw", mappingData.getString("fkdw"));
                singleData.put("skdw", mappingData.getString("skdw"));
                singleData.put("szd", mappingData.getString("szd"));
                singleData.put("skzhszd", mappingData.getString("skzhszd"));
            } else {
                log.info("银行账户信息获取为空！");
                singleData.put("fkzh", "");
                singleData.put("fkzhkhh", "");
                singleData.put("fkzhzh", "");
                singleData.put("fkzhyhzh", "");
                singleData.put("skzh", "");
                singleData.put("skzhkhh", "");
                singleData.put("skzhzh", "");
                singleData.put("skzhyhzh", "");
                singleData.put("fkdw", "");
                singleData.put("skdw", "");
                singleData.put("szd", "");
                singleData.put("skzhszd", "");
            }
            resultJson.put(onlyValue, singleData);
        }

        return resultJson;
    }

    /**
     * 组合发起资金模块资金划拨单流程数据
     *
     * @param resultJson
     */
    private String changeWorkFlowData(JSONObject resultJson, User user, String yxzjeD) throws Exception {
        log.info("组合发起资金:" + resultJson);
        ResourceComInfo rci = new ResourceComInfo();

        JSONObject json = new JSONObject();

        // 报账人          bzr                 经办人                      当前人
        JSONObject bzr = new JSONObject();
        bzr.put("name", "bzr");
        bzr.put("type", "");
        bzr.put("value", user.getUID());

        // 报账人所属部门   bzrszbm             经办人所属部门                当前人部门
        String departmentId = rci.getDepartmentID(String.valueOf(user.getUID()));
        JSONObject bzrszbm = new JSONObject();
        bzrszbm.put("name", "bzrszbm");
        bzrszbm.put("type", "");
        bzrszbm.put("value", departmentId);

        // 报账人所属单位   bzrszdw             经办人所属单位                当前人单位
        JSONObject bzrszdw = new JSONObject();
        String subCompanyId = rci.getSubCompanyID(String.valueOf(user.getUID()));
        bzrszdw.put("name", "bzrszdw");
        bzrszdw.put("type", "");
        bzrszdw.put("value", subCompanyId);

        // 报账日期        bzrq                经办人操作日期                当前日期
        String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        JSONObject bzrq = new JSONObject();
        bzrq.put("name", "bzrq");
        bzrq.put("type", "");
        bzrq.put("value", format);

        // 报账事由        bzsy                清算情况推送                  写死 “清算情况推送”
        JSONObject bzsy = new JSONObject();
        bzsy.put("name", "bzsy");
        bzsy.put("type", "");
        bzsy.put("value", "清算请款推送");

        // 划拨类型        hblx                划拨类型                      hblx
        JSONObject hblx = new JSONObject();
        hblx.put("name", "hblx");
        hblx.put("type", "");
        hblx.put("value", "");

        // 结算方式        jsfs                结算方式                      jsfs
        JSONObject jsfs = new JSONObject();
        jsfs.put("name", "jsfs");
        jsfs.put("type", "");
        jsfs.put("value", "");

        // -- 付款单位     fkdw                根据账户查询带出付款单位
        // 付款账户        fkzh                付款账户                      fkzh
        JSONObject fkzh = new JSONObject();
        fkzh.put("name", "fkzh");
        fkzh.put("type", "");
        fkzh.put("value", "");

        // 开户行          khh                 付款账户开户行                 fkzhkhh
        JSONObject khh = new JSONObject();
        khh.put("name", "khh");
        khh.put("type", "");
        khh.put("value", "");

        // 支行           zh                   付款账户支行                  fkzhzh
        JSONObject zh = new JSONObject();
        zh.put("name", "zh");
        zh.put("type", "");
        zh.put("value", "");

        // 银行账号        yhzh                付款账户银行账号               fkzhyhzh
        JSONObject yhzh = new JSONObject();
        yhzh.put("name", "yhzh");
        yhzh.put("type", "");
        yhzh.put("value", "");

        // 付款单位        fkdw                付款单位               fkdw
        JSONObject fkdw = new JSONObject();
        fkdw.put("name", "fkdw");
        fkdw.put("type", "");
        fkdw.put("value", "");

        // 所在地        szd                所在地               szd
        JSONObject szd = new JSONObject();
        szd.put("name", "szd");
        szd.put("type", "");
        szd.put("value", "");

        // 营销总金额        yxzje                营销总金额               yxzje
        JSONObject yxzje = new JSONObject();
        yxzje.put("name", "yxzje");
        yxzje.put("type", "");
        yxzje.put("value", yxzjeD);

        List<JSONObject> sonData = new ArrayList<>();

        for (Object key : resultJson.keySet()) {
            JSONObject singleSonData = new JSONObject();
            JSONObject res = resultJson.getJSONObject((String) key);
            if (hblx.get("value") == null || "".equals(hblx.get("value"))) {
                hblx.put("value", res.getString("hblx"));
            }
            if (jsfs.get("value") == null || "".equals(jsfs.get("value"))) {
                jsfs.put("value", res.getString("jsfs"));
            }

            if (fkdw.get("value") == null || "".equals(fkdw.get("value"))) {
                fkdw.put("value", res.getString("fkdw"));
            }

            if (szd.get("value") == null || "".equals(szd.get("value"))) {
                szd.put("value", res.getString("szd"));
            }

            // 明细：报销说明                    bxsm                              付款摘要                                 fkzy
            JSONObject bxsm = new JSONObject();
            bxsm.put("name", "bxsm");
            bxsm.put("type", "");
            bxsm.put("value", res.getString("fkzy"));
            singleSonData.put("bxsm", bxsm);

            // 明细：付款单位	                  fkdw                              根据账户查询带出付款单位
            // 明细：付款账户	                  fkzh                              付款账户                                 fkzh
            JSONObject fkzhD = new JSONObject();
            fkzhD.put("name", "fkzh");
            fkzhD.put("type", "");
            fkzhD.put("value", res.getString("fkzh"));
            if (fkzh.get("value") == null || "".equals(fkzh.get("value"))) {
                fkzh.put("value", res.getString("fkzh"));
            }
            singleSonData.put("fkzh", fkzhD);

            // 明细：开户行	                     fkzhkhh                        付款账户开户行                            fkzhkhh
            JSONObject fkzhkhh = new JSONObject();
            fkzhkhh.put("name", "fkzhkhh");
            fkzhkhh.put("type", "");
            fkzhkhh.put("value", res.getString("fkzhkhh"));
            if (khh.get("value") == null || "".equals(khh.get("value"))) {
                khh.put("value", res.getString("fkzhkhh"));
            }
            singleSonData.put("fkzhkhh", fkzhkhh);

            // 明细：支行	付款账户支行               fkzhzh                         付款账户支行                              fkzhzh
            JSONObject fkzhzh = new JSONObject();
            fkzhzh.put("name", "fkzhzh");
            fkzhzh.put("type", "");
            fkzhzh.put("value", res.getString("fkzhzh"));
            if (zh.get("value") == null || "".equals(zh.get("value"))) {
                zh.put("value", res.getString("fkzhzh"));
            }
            singleSonData.put("fkzhzh", fkzhzh);

            // 明细：银行账号	付款账户银行账号        fkzhyhzh                       付款账户银行账号                          fkzhyhzh
            JSONObject fkzhyhzh = new JSONObject();
            fkzhyhzh.put("name", "fkzhyhzh");
            fkzhyhzh.put("type", "");
            fkzhyhzh.put("value", res.getString("fkzhyhzh"));
            if (yhzh.get("value") == null || "".equals(yhzh.get("value"))) {
                yhzh.put("value", res.getString("fkzhyhzh"));
            }
            singleSonData.put("fkzhyhzh", fkzhyhzh);

            // 明细：金额	汇总金额                  je                              汇总金额                                hzje
            JSONObject je = new JSONObject();
            je.put("name", "je");
            je.put("type", "");
            je.put("value", res.getString("hzje"));
            singleSonData.put("je", je);

            // 明细：收款单位                      skdw                            根据账户查询带出付款单位
            // 明细：收款账户	收款账户              skzh                            收款账户                                skzh
            JSONObject skzh = new JSONObject();
            skzh.put("name", "skzh");
            skzh.put("type", "");
            skzh.put("value", res.getString("skzh"));
            singleSonData.put("skzh", skzh);

            // 明细：开户行	收款账户开户行         skzhkhh                         收款账户开户行                            skzhkhh
            JSONObject skzhkhh = new JSONObject();
            skzhkhh.put("name", "skzhkhh");
            skzhkhh.put("type", "");
            skzhkhh.put("value", res.getString("skzhkhh"));
            singleSonData.put("skzhkhh", skzhkhh);

            // 明细：支行	收款账户支行               skzhzh                          收款账户支行                             skzhzh
            JSONObject skzhzh = new JSONObject();
            skzhzh.put("name", "skzhzh");
            skzhzh.put("type", "");
            skzhzh.put("value", res.getString("skzhzh"));
            singleSonData.put("skzhzh", skzhzh);

            // 明细：银行账号	收款账户银行账号        skzhyhzh                        收款账户银行账号                         skzhyhzh
            JSONObject skzhyhzh = new JSONObject();
            skzhyhzh.put("name", "skzhyhzh");
            skzhyhzh.put("type", "");
            skzhyhzh.put("value", res.getString("skzhyhzh"));
            singleSonData.put("skzhyhzh", skzhyhzh);

            // 明细：请款批次号                    qkpch                            请款批次号                              qkpch
            JSONObject qkpch = new JSONObject();
            qkpch.put("name", "qkpch");
            qkpch.put("type", "");
            qkpch.put("value", res.getString("qkpch"));
            singleSonData.put("qkpch", qkpch);

            // 明细：收款公司                    skdw                              收款公司                                 skdw
            JSONObject skdw = new JSONObject();
            skdw.put("name", "skdw");
            skdw.put("type", "");
            skdw.put("value", res.getString("skdw"));
            singleSonData.put("skdw", skdw);

            // 明细：收款账户所在地                    skzhszd                              收款账户所在地                                 skzhszd
            JSONObject skzhszd = new JSONObject();
            skzhszd.put("name", "skzhszd");
            skzhszd.put("type", "");
            skzhszd.put("value", res.getString("skzhszd"));
            singleSonData.put("skzhszd", skzhszd);

            sonData.add(singleSonData);
        }

        json.put("bzr", bzr);
        json.put("bzrszbm", bzrszbm);
        json.put("bzrszdw", bzrszdw);
        json.put("bzrq", bzrq);
        json.put("bzsy", bzsy);
        json.put("hblx", hblx);
        json.put("jsfs", jsfs);
        json.put("fkzh", fkzh);
        json.put("khh", khh);
        json.put("zh", zh);
        json.put("yhzh", yhzh);
        json.put("fkdw", fkdw);
        json.put("szd", szd);


        json.put("sonData", sonData);

        log.info("发起资金划拨单参数：" + json);

        // 表单名+创建人+创建日期
        String title = "资金划拨单-" + user.getLastname() + "-" + format;
        log.info("资金划拨单标题：" + title);

        String fundTransferFormWorkId = com.customization.unionpay.market.util.PropUtils.BB_LOG.getPropValue("marketSubject", "fund_transfer_form_work_id");
        log.info("资金划拨单WorkId：" + fundTransferFormWorkId);
        return com.customization.unionpay.market.util.FormDataUtils.createWorkFlow(user, json, 13, 1, fundTransferFormWorkId, "0", "0", title);

    }

    /**
     * 获取映射数据
     *
     * @param actTp
     * @param zjly
     * @param sqmwh
     * @return
     */
    private JSONObject getMappingData(String actTp, String zjly, String sqmwh) {
        JSONObject res = null;
        // 营销请款-映射表表单id
        int marketingMappingFormId = Integer.parseInt(com.customization.unionpay.market.util.PropUtils.BB_LOG.getPropValue("marketSubject", "marketing_mapping_form_id"));
        String tableName = com.customization.unionpay.market.util.FormDataUtils.getTableName(marketingMappingFormId);
        return com.customization.unionpay.market.util.DailyReportBuiltMapping.selectAccInfo(tableName, zjly, actTp, sqmwh);
    }

    /**
     * 拼接预算参数
     *
     * @param yxptsxsqdh
     * @param rzje
     * @param json
     * @param instruction
     * @param user
     * @return
     * @throws Exception
     */
    public List<JSONObject> getDailyReportToMarketingApplicationParams(String yxptsxsqdh, String rzje, JSONObject json, String instruction, User user) throws Exception {
        log.info("json：" + JSONObject.toJSONString(json));
        ResourceComInfo rci = new ResourceComInfo();
        DepartmentComInfo dci = new DepartmentComInfo();
        SubCompanyComInfo scci = new SubCompanyComInfo();

        String workcode = rci.getWorkcode(String.valueOf(user.getUID()));
        String lastname = rci.getLastname(String.valueOf(user.getUID()));
        String departmentCode = dci.getDepartmentCode(rci.getDepartmentID(String.valueOf(user.getUID())));
        String departmentname = dci.getDepartmentname(rci.getDepartmentID(String.valueOf(user.getUID())));
        String subCompanyName = scci.getSubCompanyname(rci.getSubCompanyID(String.valueOf(user.getUID())));
        String subCompanyCode = scci.getSubCompanyCode(rci.getSubCompanyID(String.valueOf(user.getUID())));

        String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());

        List<JSONObject> params = new ArrayList<>();

        // 查  预算控制期
        String yskzq = json.getString("yskzq");
        // 查 项目编号
        String projectCode = json.getString("project_code");

        // 查  经济事项
        String jjsx = json.getString("jjsx");
        log.info("jjsx：" + jjsx);
        // 查  预算责任中心
        String yszrzx = json.getString("yszrzx");
        // 查  预算科目
        String yskm = json.getString("yskm");

        String yskzqStr = com.customization.unionpay.market.util.FormDataUtils.changeDateString("yyyy-MM-dd", yskzq, "yyyy");

        JSONObject param = new JSONObject();
        // 入账金额     amount                     金额	         必传
        rzje = StringUtils.isNotBlank(rzje) ? rzje : "0";
        param.put("amount", String.valueOf(Double.parseDouble(rzje) / 10000));
        // 查  预算责任中心   yszrzx  exeUnit	                执行单位	     必传，组织（预算责任中心）
        param.put("exeUnit", yszrzx);
        // 查  预算科目      yskm    budgetAccount	          	预算科目	     必传，预算科目编码
        param.put("budgetAccount", yskm);
        // 查  经济事项      jjsx    economicEvent              经济事项     必传，经济事项编号
        param.put("economicEvent", jjsx);
        //  营销日报表台账               exeDocType	                执行单据类型	必传
        param.put("exeDocType", "核算入账");
        //                            executionDate	            执行日期	    必传，当前日期
        param.put("executionDate", format);
        //                            sourceSystem	            来源系统	    必传，智慧财务平台
        param.put("sourceSystem", "智慧财务平台");
        // 查 预算控制期      yskzq     budgetPostingPeriod       预算控制期     必传，预算的入账期间
        param.put("budgetPostingPeriod", yskzq);
        //                            budgetPeriod              预算期间（年）	 必传，预算入账期间加工成4位年份
        param.put("budgetPeriod", yskzqStr);
        // 查 项目编号                  budgetItem                 预算项目      必传，项目编号
        param.put("budgetItem", projectCode);
        //  原事项申请单号               exeDocNo                  执行单据号    必传
        param.put("exeDocNo", yxptsxsqdh);
        //  原事项申请单号               occDocNo                  被占用单据号	 非必传，下列情况必传： 释放占用且执行,释放执行且占用、释放占用（必传）, 占用（特殊情况必传）
        param.put("occDocNo", yxptsxsqdh);
        //  当前人                    claimant                  报账人         必传，工号-姓名
        param.put("claimant", workcode + "-" + lastname);
        //  当前部门                 reimbursementDept          报账部门       必传，部门编码-部门名称
        param.put("reimbursementDept", departmentCode + "-" + departmentname);
        //  当前公司                 reimbursementCompany       报账公司        必传，公司编码-公司名称
        param.put("reimbursementCompany", subCompanyCode + "-" + subCompanyName);
        //  营销日报表台账核算入账      remark   必传，各报账单的主表备注字段
        param.put("remark", "营销日报表台账核算入账");
        //                            instruction                 指令            必传，指令对应编码如下： 占用-ZY 释放占用且执行-SFZYQZX 仅项目占用-XMZY 仅项目释放占用且执行-XMSFZYQZX
        param.put("instruction", instruction);
        params.add(param);

        return params;
    }

}
